package com.locationtracker.plus.ui.fragment.pay

import android.os.Bundle
import android.text.Html
import android.text.Spanned
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.android.billingclient.api.*
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ThreadUtils.runOnUiThread
import com.blankj.utilcode.util.ToastUtils
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.locationtracker.plus.R
import com.locationtracker.plus.app.base.BaseFragment
import com.locationtracker.plus.app.eventViewModel
import com.locationtracker.plus.app.ext.init
import com.locationtracker.plus.app.util.CacheUtil
import com.locationtracker.plus.app.weight.recyclerview.decoration.GridItemDecoration
import com.locationtracker.plus.data.model.bean.RechargeResponse
import com.locationtracker.plus.databinding.FragmentRechargeBinding
import com.locationtracker.plus.ui.adapter.RechargeAdapter
import com.locationtracker.plus.viewmodel.request.RequestPayViewModel
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.navigateAction
import me.hgj.jetpackmvvm.ext.parseState
import me.hgj.jetpackmvvm.ext.util.dp2px
import me.hgj.jetpackmvvm.ext.util.notNull

const val AD_UNIT_ID = "ca-app-pub-4579422483792864/6770574590"

class RechargeFragment : BaseFragment<BaseViewModel, FragmentRechargeBinding>() {
    private var connectionCount = 0
    private var connectionErrorStr = ""
    private val skuList by lazy { mutableListOf<SkuDetails>() }

    var purchaseTime = 0L//购买时间
    private var foreverSku: RechargeResponse? = null//订阅成功后传永久那个sku

    private val switchText by lazy { mutableListOf<Spanned>() }

    private val mAdapter by lazy { RechargeAdapter(arrayListOf()) }

    private val requestPayViewModel by viewModels<RequestPayViewModel>()

    //广告
    private var mAdIsLoading: Boolean = false
    private var mInterstitialAd: InterstitialAd? = null

    private val acknowledgePurchaseResponseListener by lazy {
        AcknowledgePurchaseResponseListener {
            dismissLoading()
            when (it.responseCode) {
                BillingClient.BillingResponseCode.OK -> actionAfterBuy()
                BillingClient.BillingResponseCode.USER_CANCELED -> {
                    //用户取消购买
                    //处理由用户取消采购流程引起的错误。
//                    ToastUtils.showShort("Transaction cancelled")
                    showAd(false)
                }
                else -> {
                    //处理任何其他错误代码。
                    if (it.debugMessage.isNotEmpty())
                        ToastUtils.showShort(it.debugMessage)
                }
            }
        }
    }

    //处理购买交易
    private fun handlePurchase(purchase: Purchase) {
        purchaseTime = purchase.purchaseTime

        val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
            .setPurchaseToken(purchase.purchaseToken)
            .build()

        showLoading()
        billingClient.acknowledgePurchase(
            acknowledgePurchaseParams,
            acknowledgePurchaseResponseListener
        )
    }

    private val connection: () -> Unit = {
        lifecycleScope.launch {
            withContext(Dispatchers.IO) {
                connectionCount++
                billingClient.startConnection(billingClientStateListener)
            }
        }
    }

    private val billingClientStateListener by lazy {
        object : BillingClientStateListener {
            override fun onBillingServiceDisconnected() {
                flow {
                    emit("")
                    delay(connectionCount * 3000L)
                }.onCompletion { connection.invoke() }
                    .launchIn(lifecycleScope)
            }

            override fun onBillingSetupFinished(p0: BillingResult) {
                dismissLoading()
                if (p0.responseCode == BillingClient.BillingResponseCode.OK) {
                    connectionCount = 0
                    lifecycleScope.launch { processPurchases() }
                } else {
                    connectionErrorStr = p0.debugMessage
                    flow {
                        emit("")
                        delay(connectionCount * 3000L)
                    }.onCompletion { connection.invoke() }
                        .launchIn(lifecycleScope)
                }
            }
        }
    }

    private val billingClient by lazy {
        BillingClient.newBuilder(mActivity)
            .setListener { billingResult, purchases ->
                // 接收应用中所有购买交易的更新
                LogUtils.i(
                    "PurchasesUpdatedListener:" + GsonUtils.toJson(billingResult) + "===>" + GsonUtils.toJson(
                        purchases
                    )
                )
                //购买结果监听
                if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && !purchases.isNullOrEmpty()) {
                    var purchased = false
                    //购买成功
                    for (purchase in purchases) {
                        //验证购买情况。//确保尚未为此purchaseToken授予权限。//授予用户权限。
                        when (purchase.purchaseState) {
                            Purchase.PurchaseState.PENDING -> handlePurchase(purchase)
                            Purchase.PurchaseState.PURCHASED -> if (purchase.isAcknowledged) {
//                                if (purchase.isAutoRenewing) {
                                purchaseTime = purchase.purchaseTime
                                purchased = true
//                                }
                            } else {
                                handlePurchase(purchase)
                            }
                            else -> {
                                handlePurchase(purchase)
                            }
                        }
                    }

                    if (purchased) { actionAfterBuy() }
                } else if (billingResult.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
                    //用户取消购买
                    //处理由用户取消采购流程引起的错误。
//            ToastUtils.showShort("Transaction cancelled")
                    showAd(false)
                } else {
                    //处理任何其他错误代码。
                    if (billingResult.debugMessage.isNotEmpty())
                        ToastUtils.showShort(billingResult.debugMessage)
                }
            }
            .enablePendingPurchases()
            .build()
    }

    override fun initView(savedInstanceState: Bundle?) {
        mDatabind.click = ProxyClick()
        mDatabind.includeHeader.headerBack.setOnClickListener {
            nav().navigateUp()
//            mInterstitialAd.notNull({ showAd(true) }, { nav().navigateUp() })
        }

        mDatabind.textSwitcherView.setSwitcherLayout(R.layout.item_switcher_view)

        mDatabind.rechargeRecycler.init(
            GridLayoutManager(mActivity, 3),
            mAdapter
        ).let {
            if (it.itemDecorationCount == 0)
                it.addItemDecoration(
                    GridItemDecoration.Builder(activity)
                        .size(mActivity.dp2px(11))
                        .margin(mActivity.dp2px(15), mActivity.dp2px(15))
                        .build()
                )
        }
        mAdapter.setOnItemClickListener { _, _, position ->
            mAdapter.data.forEachIndexed { index, item ->
                item.selected = index != position
            }
            mAdapter.notifyDataSetChanged()
        }
        requestPayViewModel.updateEvent("sellpage")
        showLoading("Connect to billing")
        connection.invoke()

        if (!mAdIsLoading && mInterstitialAd == null) {
            loadAd()
        }
    }

    private fun showAd(finish: Boolean) {
        //每隔30s弹出一次广告
//        if (System.currentTimeMillis() - CacheUtil.getLastAdTime() >= 30 * 1000) {
//            mInterstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
//                override fun onAdDismissedFullScreenContent() {
//                    "Ad was dismissed.".logd()
//                    // Don't forget to set the ad reference to null so you
//                    // don't show the ad a second time.
//    //                mInterstitialAd = null
//                    if (finish) nav().navigateUp()
//                    else loadAd()
//                }
//
//                override fun onAdFailedToShowFullScreenContent(adError: AdError) {
//                    "Ad failed to show.".logd()
//                    // Don't forget to set the ad reference to null so you
//                    // don't show the ad a second time.
//    //                    mInterstitialAd = null
//                    loadAd()
//                }
//
//                override fun onAdShowedFullScreenContent() {
//                    "Ad showed fullscreen content.".logd()
//                    // Called when ad is dismissed.
//                }
//            }
//            mInterstitialAd?.show(mActivity)
//            CacheUtil.setLastAdTime(System.currentTimeMillis())
//        }
    }

    private fun loadAd() {
//        mAdIsLoading = true
//        InterstitialAd.load(
//            mActivity,
//            AD_UNIT_ID,
//            AdRequest.Builder().build(),
//            object : InterstitialAdLoadCallback() {
//                override fun onAdFailedToLoad(adError: LoadAdError) {
//                    adError.message.logd()
//                    mInterstitialAd = null
//                    mAdIsLoading = false
//                    val error =
//                        "domain: ${adError.domain}, code: ${adError.code}, " + "message: ${adError.message}"
//                }
//
//                override fun onAdLoaded(interstitialAd: InterstitialAd) {
//                    "Ad was loaded.".logd()
//                    mInterstitialAd = interstitialAd
//                    mAdIsLoading = false
//                }
//            }
//        )
    }

    override fun lazyLoadData() {
        requestPayViewModel.productList()
    }

    override fun onResume() {
        super.onResume()
        mDatabind.textSwitcherView.startPlay()
    }

    override fun onPause() {
        super.onPause()
        mDatabind.textSwitcherView.stopPlay()
    }

    override fun onDestroy() {
        super.onDestroy()
        billingClient.endConnection()
    }

    override fun createObserver() {
        requestPayViewModel.productListData.observe(viewLifecycleOwner) { resultState ->
            parseState(resultState, {
                if (it.isNotEmpty()) it[0].selected = false
                if (it.size >= 3) foreverSku = it[2] //最后一个就是永久订阅
                mAdapter.setList(it)
                initSwitch()
            })
        }
    }

    suspend fun processPurchases() {
        skuList.clear()
        showLoading("Query sku")
        skuList.addAll(withContext(Dispatchers.IO) {
            val resultList = mutableListOf<SkuDetails>()
            val subsData = async {
                billingClient.querySkuDetails(
                    SkuDetailsParams.newBuilder()
                        .setSkusList(mutableListOf("location_month_vip", "location_quarter_vip"))
                        .setType(BillingClient.SkuType.SUBS)
                        .build()
                )
            }
            val inAppData = async {
                billingClient.querySkuDetails(
                    SkuDetailsParams.newBuilder()
                        .setSkusList(mutableListOf("location_lifelong_vip"))
                        .setType(BillingClient.SkuType.INAPP)
                        .build()
                )
            }
            subsData.await().skuDetailsList?.let { resultList.addAll(it) }
            inAppData.await().skuDetailsList?.let { resultList.addAll(it) }
            resultList
        })
        dismissLoading()
    }

    private fun initSwitch() {
        if (mAdapter.data.isEmpty()) return
        switchText.clear()
        repeat(10) {
            switchText.add(
                Html.fromHtml(
                    "***-****-${
                        (100..999).random().toString().let {
                            when (it.length) {
                                1 -> "00$it"
                                2 -> "0$it"
                                else -> it
                            }
                        }
                    }   Just Start a <font color=\"#1FD08C\">${
                        mAdapter.data.random().name
                    }</font> VIP"
                )
            )
        }
        mDatabind.textSwitcherView.setData(switchText)
    }

    private fun actionAfterBuy() {
        runOnUiThread {
            ToastUtils.showShort("success")
            requestPayViewModel.updateEvent("buy_success") //打点
            foreverSku?.let { CacheUtil.setForeverId(it.id) } //记录已订购
            eventViewModel.acknowledgementDialogEvent.value = System.currentTimeMillis() //知情弹框并登陆
            nav().navigateUp()
        }
    }

    inner class ProxyClick {
        fun agreementTerms() {
            nav().navigateAction(
                R.id.action_to_webFragment,
                bundleOf("url" to "https://kdocs.cn/l/cg1uOJLTlx5O")
            )
        }

        fun agreementPrivacy() {
            nav().navigateAction(
                R.id.action_to_webFragment,
                bundleOf("url" to "https://kdocs.cn/l/cdq62si0A72i")
            )
        }

        fun submit() {
            if (!mAdIsLoading && mInterstitialAd == null) loadAd()
            if (!mDatabind.rechargeCheck.isChecked) {
                ToastUtils.showShort("Please read and agree the policy")
                return
            }
            if (skuList.isEmpty()) {
                if (connectionCount > 0) {
                    if (connectionCount >= 3 && connectionErrorStr.isNotEmpty()) {
                        ToastUtils.showLong(connectionErrorStr)
                    }
                    showLoading("Connect to billing")
                    connection.invoke()
                } else {
                    lifecycleScope.launch { processPurchases() }
                }
            }
            mAdapter.data.forEach { responseData ->
                if (!responseData.selected) { //选中的
                    skuList.find { sku ->
                        sku.sku == responseData.google_goods_id
                    }.notNull({
                        //去支付
                        val responseCode = billingClient.launchBillingFlow(
                            mActivity, BillingFlowParams.newBuilder()
                                .setSkuDetails(it)
                                .build()
                        ).responseCode
                    }, {
                        //没有找到对应的sku
                        lifecycleScope.launch { processPurchases() }
                    })
                    return
                }
            }
        }
    }
}